package my.xiaobei_auto.controller;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import my.xiaobei_auto.common.Result;
import my.xiaobei_auto.common.ResultEnum;
import my.xiaobei_auto.common.ResultModel;
import my.xiaobei_auto.pojo.StudentAccount;
import my.xiaobei_auto.vo.ListHealthResultVO;
import my.xiaobei_auto.vo.XbLoginVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("student")
@Slf4j
/**
 * 学生操作
 */
public class StudentController {

    /**
     * 添加账号
     * @param xbLoginVO
     * @return
     * @throws SQLException
     */
    @PostMapping("xbLogin")
    public Result<String> xbLogin(@Valid XbLoginVO xbLoginVO) throws SQLException {
        String password = xbLoginVO.getPassword();

        xbLoginVO.setPassword(Base64.encode(password));
        String data = JSONUtil.toJsonStr(xbLoginVO);
        String res = HttpUtil.post("https://xiaobei.yinghuaonline.com/xiaobei-api/login", data);

        JSONObject jsonObject = JSONUtil.parseObj(res);

        if ("200".equals(jsonObject.get("code").toString())) {
            // 查询账号是否存在
            List<Entity> all = Db.use().findAll(
                    Entity.create("student_account")
                            .set("xb_account", xbLoginVO.getUsername())
                            .set("is_deleted", 0));
            if (all.size() > 0){
                // 更新数据
                int update = Db.use().update(
                        Entity.create().set("xb_password", password)
                                .set("xb_token", jsonObject.get("token")), //修改的数据
                        Entity.create("student_account").set("xb_account", xbLoginVO.getUsername()) //where条件
                );
                if (update > 0){
                    return ResultModel.success(jsonObject.get("token"));
                }
                return ResultModel.error(ResultEnum.SYSTEM_RUN_REEOR);
            }

            // 添加数据
            int insert = Db.use().insert(Entity.create("student_account")
                    .set("xb_account", xbLoginVO.getUsername())
                    .set("xb_password", password)
                    .set("xb_token", jsonObject.get("token"))
                    .set("is_deleted", 0));
            if (insert > 0){
                return ResultModel.success(jsonObject.get("token"));
            }
            return ResultModel.error(ResultEnum.SYSTEM_RUN_REEOR);
        }
        return ResultModel.error(ResultEnum.USER_PASSWORD_ERROR);
    }

    /**
     * 单个账号打卡
     * @param token 账号Token
     * @return
     */
    @GetMapping("healthOne")
    public String healthOne(@Valid @NotBlank String token){
        // 打卡数据
        String data = """
                {
                  "location" : "110.2965801323785,25.06140597873264",
                  "dangerousRegion" : "2",
                  "goOutRemark" : "",
                  "dangerousRegionRemark" : "",
                  "remark" : "",
                  "goOut" : "1",
                  "familySituation" : "1",
                  "temperature" : "36",
                  "healthState" : "1",
                  "coordinates" : "undefined-广西壮族自治区-桂林市-雁山区",
                  "contactSituation" : "2"
                }
                """;

        String res = HttpRequest.post("https://xiaobei.yinghuaonline.com/xiaobei-api/student/health")
                .header("Authorization", token)
                .header("User-Agent", "iPad11,1(iOS/15.1) Uninview(Uninview/1.0.0) Weex/0.26.0 1536x2048")
                .body(data)
                .execute().body();

        return res;

    }

    /**
     * 遍历账号打卡
     * @throws SQLException
     */
    @GetMapping("listHealth")
    public Result<ListHealthResultVO> listHealth() throws SQLException {
        log.info("启动打卡");
        List<ListHealthResultVO> resList = new ArrayList();

        // 获取数据库账号信息
//        List<Entity> studentAccount = Db.use().findAll("student_account");
        List<Entity> studentAccount = Db.use().findAll(
                Entity.create("student_account")
                        .set("is_deleted", false)
        );
        for (Entity sa : studentAccount){
            StudentAccount stu = sa.toBean(StudentAccount.class);

            // 调用打卡方法
            String res = healthOne(stu.getXbToken());

            JSONObject jsonObject = JSONUtil.parseObj(res);

            String code = jsonObject.get("code").toString();
            if ("200".equals(code)) {
                // 打卡成功
                resList.add(new ListHealthResultVO(stu.getXbAccount(), res));
                continue;
            }else if ("401".equals(code)){
                // 认证失败, 重新获取认证
                Result resultLogin = xbLogin(new XbLoginVO(stu.getXbAccount(), stu.getXbPassword()));
                if ("A0210".equals(resultLogin.getCode())){
                    // 重新认证失败
                    Db.use().update(
                            Entity.create().set("is_deleted", true), //修改的数据
                            Entity.create("student_account").set("id", stu.getId()) //where条件
                    );
                    log.info("id: " + stu.getId() +  "-----账号：" + stu.getXbAccount() + "-----重新认证失败，移除打卡队列");
                    continue;
                }
                // 查询重新查询数据库
                List<Entity> entities = Db.use().find(
                        Entity.create("student_account")
                                .filter("xb_token")
                                .set("id", stu.getId())
                                .set("is_deleted", false));

                StudentAccount againStudent = entities.get(0).toBean(StudentAccount.class);
                // 再次打卡
                String againRes = healthOne(againStudent.getXbToken());
                JSONObject againJson = JSONUtil.parseObj(againRes);
//                System.err.println(againJson);
                if ("200".equals(againJson.get("code").toString())) {
                    // 打卡成功
                    String xbAccount = stu.getXbAccount();
                    resList.add(new ListHealthResultVO(DesensitizedUtil.idCardNum(xbAccount, 4, 4), againRes));
                    continue;
                }
                // 失败
                resList.add(new ListHealthResultVO(stu.getXbAccount(), againRes));
                log.info("id: " + stu.getId() +  "-----账号：" + stu.getXbAccount() + "-----打卡失败");
            }else {
                // 打卡失败
                resList.add(new ListHealthResultVO(stu.getXbAccount(), res));
                log.info("id: " + stu.getId() +  "-----账号：" + stu.getXbAccount() + "-----打卡失败");
            }
        }
        log.info("打卡信息：" + resList);
        log.info("打卡结束");
        return ResultModel.success(resList);
    }
}
